package com.ssy.lingxi.member.merchant.serviceimpl.base;

import com.ssy.lingxi.common.constant.basic.EnableDisableStatus;
import com.ssy.lingxi.common.constant.member.MemberLevelTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberStatusEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.exception.BusinessException;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.api.model.constant.MemberProcessTypeEnum;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.bo.*;
import com.ssy.lingxi.member.merchant.model.constant.*;
import com.ssy.lingxi.member.merchant.model.vo.validate.request.MemberQualityVO;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.*;
import com.ssy.lingxi.member.merchant.service.feign.*;
import com.ssy.lingxi.member.merchant.service.web.IMemberProcessRuleService;
import com.ssy.lingxi.member.merchant.utils.AuthBOUtils;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员、用户内部服务类实现
 * @author 万宁
 * @version 2.0.0
 * @date 2020-08-06
 */
@Service
public class BaseMemberInnerServiceImpl implements IBaseMemberInnerService {
    @Resource
    private MemberRepository memberRepository;

    @Resource
    private MemberAuthRepository memberAuthRepository;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private MemberRelationAuthRepository relationAuthRepository;

    @Resource
    private MemberRegisterDetailRepository memberRegisterDetailRepository;

    @Resource
    private MemberDepositoryDetailRepository memberDepositoryDetailRepository;

    @Resource
    private MemberQualityRepository memberQualityRepository;

    @Resource
    private MemberRoleRepository memberRoleRepository;

    @Resource
    private MemberUserRepository memberUserRepository;

    @Resource
    private MemberUserAuthRepository memberUserAuthRepository;

    @Resource
    private IBaseMemberDepositDetailService baseMemberDepositDetailService;

    @Resource
    private IBaseMemberQualificationService baseMemberQualificationService;

    @Resource
    private ChannelTypeRepository channelTypeRepository;

    @Resource
    private MemberLevelConfigRepository memberLevelConfigRepository;

    @Resource
    private MemberLevelRuleConfigRepository memberLevelRuleConfigRepository;

    @Resource
    private MemberRightConfigRepository memberRightConfigRepository;

    @Resource
    private MemberLevelRightRepository memberLevelRightRepository;

    @Resource
    private MemberCreditRepository memberCreditRepository;

    @Resource
    private IBaseMemberHistoryService baseMemberHistoryService;

    @Resource
    private MemberAfterSaleHistoryRepository memberAfterSaleHistoryRepository;

    @Resource
    private MemberComplainHistoryRepository memberComplainHistoryRepository;

    @Resource
    private MemberTradeCommentHistoryRepository memberTradeCommentHistoryRepository;

    @Resource
    private MemberLevelHistoryRepository memberLevelHistoryRepository;

    @Resource
    private MemberRightHistoryRepository memberRightHistoryRepository;

    @Resource
    private MemberRightSpendHistoryRepository memberRightSpendHistoryRepository;

    @Resource
    private MemberOrganizationRepository memberOrganizationRepository;

    @Resource
    private IBaseMemberLevelConfigService baseMemberLevelConfigService;

    @Resource
    private IMemberProcessRuleService memberProcessRuleService;

    @Resource
    private IWorkflowFeignService workflowFeignService;

    @Resource
    private IReportFeignService reportFeignService;

    @Resource
    private IMessageFeignService messageFeignService;

    @Resource
    private IPayFeignService payFeignService;

    @Resource
    private ILogisticsFeignService logisticsFeignService;

    /**
     * 新增会员
     * @param memberBO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<MemberRelationDO> addPlatformMember(AddMemberBO memberBO) {
        //新增会员
        MemberDO memberDO = new MemberDO();
        //注册时间
        memberDO.setRegisterTime(LocalDateTime.now());
        //设置会员名称
        memberDO.setName(memberBO.getName());
        //设置邮箱
        memberDO.setEmail(memberBO.getEmail());
        //设置支付密码为空
        memberDO.setPayPassword("");
        //注册来源
        memberDO.setSource(memberBO.getSource().getCode());
        //会员头像
        memberDO.setLogo("");
        //密码
        memberDO.setPassword(memberBO.getPassword());
        //通过注册页面的都是商家，手机号即账号
        memberDO.setCountryCode(memberBO.getCountryCode());
        memberDO.setPhone(memberBO.getPhone());
        memberDO.setAccount(memberBO.getPhone());
        //设置角色和权限
        Set<RoleDO> roleDoSet = new HashSet<>();
        roleDoSet.add(memberBO.getRoleDO());
        memberDO.setRoles(roleDoSet);

        MemberAuthDO memberAuth = new MemberAuthDO();
        memberAuth.setAuth(memberBO.getRoleDO().getRoleAuth().getAuth());
        memberAuth.setMember(memberDO);
        memberDO.setMemberAuth(memberAuth);

        //由于关联关系是CascadeType.DETACH，所以要先保存一下注册信息，再更新
        List<MemberRegisterDetailDO> memberRegisterDetails = memberBO.getRegisterDetails();
        memberRegisterDetailRepository.saveAll(memberRegisterDetails);

        memberDO.setRegisterDetails(new HashSet<>(memberRegisterDetails));
        memberRepository.saveAndFlush(memberDO);

        memberRegisterDetails.forEach(memberRegisterDetailDO -> {
            memberRegisterDetailDO.setMember(memberDO);
            //如果是“无需审核”流程，将注册资料版本设置为“正在使用”
            if(memberBO.getPlatformProcess().getEmptyProcess()) {
                memberRegisterDetailDO.setVersion(MemberDetailVersionEnum.USING.getCode());
            }
        });

        memberRegisterDetailRepository.saveAll(memberRegisterDetails);

        //第二步骤：创建上下级关系，以及审核状态
        MemberRelationDO relationDO = new MemberRelationDO();
        relationDO.setCreateTime(LocalDateTime.now());
        relationDO.setMemberId(memberBO.getUpperMember().getId());
        relationDO.setMember(memberBO.getUpperMember());
        relationDO.setRoleId(memberBO.getUpperRole().getId());
        relationDO.setRole(memberBO.getUpperRole());
        relationDO.setSubMemberId(memberDO.getId());
        relationDO.setSubMember(memberDO);
        relationDO.setSubMemberTypeEnum(memberBO.getMemberTypeDO().getTypeEnum());
        //上级为平台，所以等级类型为平台会员
        relationDO.setSubMemberLevelTypeEnum(MemberLevelTypeEnum.PLATFORM.getCode());
        relationDO.setSubRoleId(memberBO.getRoleDO().getId());
        relationDO.setSubRole(memberBO.getRoleDO());
        relationDO.setSubRoleName(memberBO.getRoleDO().getRoleName());
        relationDO.setRelType(MemberRelationTypeEnum.PLATFORM.getCode());
        relationDO.setRelSource(MemberRelationSourceEnum.parseFromRegisterSource(memberBO.getSource()).getCode());
        //初始的审核状态、外部状态
        relationDO.setVerified(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode());
        relationDO.setOuterStatus(MemberOuterStatusEnum.PLATFORM_VERIFYING.getCode());

        relationDO.setStatus(MemberStatusEnum.NORMAL.getCode());
        relationDO.setValidateMsg("");

        //平台会员不需要配置渠道渠道信息
        relationDO.setChannel(null);

        //权限
        MemberRelationAuthDO relationAuth = new MemberRelationAuthDO();
        relationAuth.setAuth(memberAuth.getAuth());
        relationAuth.setRelation(relationDO);

        relationDO.setRelationAuth(relationAuth);
        //由于工作流需要dataId（不能为空或0），所以要先保存一下MemberRelationDO
        relationRepository.saveAndFlush(relationDO);

        //第二步骤：调用工作流模块
        String taskId = "";
        Integer innerStatus = memberBO.getInnerStatus();
        if(!memberBO.getInnerStatus().equals(PlatformInnerStatusEnum.REGISTERING.getCode())) {
            //如果是无需审核流程，直接设置最终状态
            if(memberBO.getPlatformProcess().getEmptyProcess()) {
                innerStatus = PlatformInnerStatusEnum.VERIFY_PASSED.getCode();
                relationDO.setOuterStatus(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode());
                relationDO.setVerified(MemberValidateStatusEnum.VERIFY_PASSED.getCode());
                relationDO.setDepositTime(LocalDateTime.now());
            } else {
                //内部状态从工作流模块获得，内部审核流程使用memberId，roleId两个参数
                Wrapper<WorkflowTaskResultBO> taskResult = workflowFeignService.startMemberProcess(memberBO.getPlatformProcess().getProcessKey(), relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getId());
                if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VALIDATE_WORKFLOW_ERROR);
                }

                taskId = taskResult.getData().getTaskId();
                innerStatus = taskResult.getData().getInnerStatus();

                //最终审核状态
                if (!StringUtils.hasLength(taskId)) {
                    relationDO.setOuterStatus(innerStatus.equals(PlatformInnerStatusEnum.VERIFY_PASSED.getCode()) ? MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode() : MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode());
                    relationDO.setVerified(innerStatus.equals(PlatformInnerStatusEnum.VERIFY_PASSED.getCode()) ? MemberValidateStatusEnum.VERIFY_PASSED.getCode() : MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode());
                    relationDO.setDepositTime(innerStatus.equals(PlatformInnerStatusEnum.VERIFY_PASSED.getCode()) ? LocalDateTime.now() : null);
                }
            }
        }

        //内部状态、工作流任务
        relationDO.setInnerStatus(innerStatus);
        relationDO.setValidateTask(new MemberValidateTaskDO(taskId, memberBO.getPlatformProcess().getProcessKey(), MemberProcessTypeEnum.PLATFORM_VALIDATION.getCode()));

        relationRepository.saveAndFlush(relationDO);

        //如果level是Null，查询最小等级；否则查询指定等级
        MemberLevelConfigDO upperMemberLevelConfigDO;
        if(NumberUtil.isNullOrZero(memberBO.getLevel())) {
            upperMemberLevelConfigDO = baseMemberLevelConfigService.findFirstLevel(relationDO);
        } else {
            upperMemberLevelConfigDO = baseMemberLevelConfigService.findLevel(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubRoleId(), memberBO.getLevel());
        }

        MemberLevelRightDO levelDO = new MemberLevelRightDO();
        levelDO.setMemberId(memberBO.getUpperMember().getId());
        levelDO.setRoleId(memberBO.getUpperRole().getId());
        levelDO.setSubMemberId(memberDO.getId());
        levelDO.setSubRoleId(memberBO.getRoleDO().getId());
        levelDO.setLevel(upperMemberLevelConfigDO == null ? 0 : upperMemberLevelConfigDO.getLevel());
        levelDO.setLevelTag(upperMemberLevelConfigDO == null ? "" : upperMemberLevelConfigDO.getLevelTag());
        levelDO.setLevelConfig(upperMemberLevelConfigDO);
        levelDO.setScore(0);
        levelDO.setCurrentPoint(0);
        levelDO.setSumPoint(0);
        levelDO.setSumReturnMoney(new BigDecimal(0));
        levelDO.setSumUsedPoint(0);
        levelDO.setRelation(relationDO);

        //设置信用信息
        MemberCreditDO creditDO = new MemberCreditDO();
        creditDO.setMemberId(memberBO.getUpperMember().getId());
        creditDO.setRoleId(memberBO.getUpperRole().getId());
        creditDO.setSubMemberId(memberDO.getId());
        creditDO.setSubRoleId(memberBO.getRoleDO().getId());
        creditDO.setAfterSaleCommentPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setCreditPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setRegisterYearsPoint(0);
        creditDO.setTradeCommentPoint(0);
        creditDO.setRelation(relationDO);
        creditDO.setRegisterPointUpdateTime(LocalDateTime.now());
        creditDO.setTradeCommentStars(0);
        creditDO.setTradeCommentCount(0);
        creditDO.setAvgTradeCommentStar(ServiceConfig.DEFAULT_TRADE_COMMENT_STAR);

        //关联到会员关系
        relationDO.setLevelRight(levelDO);
        relationDO.setCredit(creditDO);
        relationRepository.saveAndFlush(relationDO);

        //第四步骤: 创建“超级管理员”角色 与 超级管理员用户
        //由于注册后就可以登录首页，所以注册的同时要创建用户
        MemberRoleDO memberRoleDO = new MemberRoleDO();
        memberRoleDO.setRoleName(MemberUserAuthTypeEnum.ADMIN.getMessage());
        memberRoleDO.setTypeEnum(MemberUserAuthTypeEnum.ADMIN.getCode());
        //默认具有IM即时通信权限
        memberRoleDO.setHasImAuth(EnableDisableStatus.ENABLE.getCode());
        //会员超级管理员角色不需要设置数据权限
        memberRoleDO.setAuthConfig(new HashSet<>());
        //菜单权限设置
        memberRoleDO.setAuth(memberBO.getRoleDO().getRoleAuth().getAuth());
        memberRoleDO.setRemark(MemberStringEnum.MEMBER_ADMIN_ROLE_DEFAULT_REMARK.getName());
        memberRoleDO.setStatus(EnableDisableStatus.ENABLE.getCode());
        memberRoleDO.setMember(memberDO);
        memberRoleRepository.saveAndFlush(memberRoleDO);

        Set<MemberRoleDO> memberRoleSet = new HashSet<>();
        memberRoleSet.add(memberRoleDO);
        memberDO.setMemberRoles(memberRoleSet);

        //Step 2: 创建 超级管理员用户
        MemberUserDO userDO = new MemberUserDO();
        userDO.setCreateTime(LocalDateTime.now());
        userDO.setAccount(memberDO.getAccount());
        userDO.setPhone(memberDO.getPhone());
        userDO.setPassword(memberDO.getPassword());
        userDO.setCountryCode(memberDO.getCountryCode());
        userDO.setName(memberDO.getName());
        userDO.setEmail(memberDO.getEmail());
        userDO.setIdCardNo("");
        userDO.setJobTitle(MemberStringEnum.PLATFORM_SUPER_ADMIN_JOB_TITLE.getName());
        userDO.setLogo("");
        userDO.setStatus(EnableDisableStatus.ENABLE.getCode());
        userDO.setRelType(MemberRelationTypeEnum.OTHER.getCode());
        userDO.setTypeEnum(MemberUserAuthTypeEnum.ADMIN.getCode());
        userDO.setIsSales(EnableDisableStatus.DISABLE.getCode());
        userDO.setMember(memberDO);
        userDO.setRoles(memberRoleSet);
        //超级管理员用户不需要设置数据权限、渠道权限
        MemberUserAuthDO userAuth = new MemberUserAuthDO();
        userAuth.setAuth(memberAuth.getAuth());
        userAuth.setUser(userDO);
        userAuth.setDataAuth(new ArrayList<>());
        userAuth.setChannelAuth(new ArrayList<>());
        userAuth.setChannels(new HashSet<>());
        userDO.setUserAuth(userAuth);

        memberUserRepository.saveAndFlush(userDO);

        Set<MemberUserDO> memberUserSet = new HashSet<>();
        memberUserSet.add(userDO);
        memberDO.setUsers(memberUserSet);
        memberRepository.saveAndFlush(memberDO);

        //第六步骤：“注册”的审核记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, memberBO.getOperatorRoleName(), MemberValidateHistoryOperationEnum.REGISTER, MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()), "");

        //第七步骤：异步通知报表服务、实时消息服务、支付服务
        reportFeignService.reportPlatformMemberValidate(relationDO.getId(), relationDO.getMemberId(), relationDO.getRoleId(), null, innerStatus);
        messageFeignService.sendMemberValidateMessage(relationDO);
        payFeignService.notifyMemberAssetAccount(relationDO);
        payFeignService.notifyMemberCredit(relationDO);
        logisticsFeignService.initMemberLogisticsAsync(relationDO);

        return Wrapper.success(relationDO);
    }

    /**
     * 会员能力 - 新增会员上下级关系（非平台会员）
     * @param upperMember 上级会员
     * @param upperRole   上级会员角色
     * @param subMemberPlatformRelation   下级会员的平台会员关系
     * @param subRole     下级会员角色
     * @param subMemberType 下级会员的会员类型
     * @param subMemberLevel  下级会员的等级
     * @param subMemberLevelTypeEnum 下级会员的等级类型
     * @param subMemberChannel  下级会员的渠道信息
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> addMemberRelation(MemberDO upperMember, RoleDO upperRole, MemberRelationDO subMemberPlatformRelation, RoleDO subRole, MemberTypeDO subMemberType, Integer subMemberLevel, Integer subMemberLevelTypeEnum, MemberChannelDO subMemberChannel) {
        MemberDO subMember = subMemberPlatformRelation.getSubMember();
        //创建上下级关系，以及审核状态
        MemberRelationDO relationDO = new MemberRelationDO();
        relationDO.setCreateTime(LocalDateTime.now());
        relationDO.setMemberId(upperMember.getId());
        relationDO.setMember(upperMember);
        relationDO.setUserId(0L);
        relationDO.setRoleId(upperRole.getId());
        relationDO.setRole(upperRole);
        relationDO.setSubMemberId(subMember.getId());
        relationDO.setSubMember(subMember);
        relationDO.setSubRoleId(subRole.getId());
        relationDO.setSubRole(subRole);
        relationDO.setSubRoleName(subRole.getRoleName());
        relationDO.setSubMemberTypeEnum(subMemberType.getTypeEnum());
        relationDO.setSubMemberLevelTypeEnum(subMemberLevelTypeEnum);
        relationDO.setRelType(MemberRelationTypeEnum.OTHER.getCode());
        relationDO.setRelSource(MemberRelationSourceEnum.MEMBER_CREATE.getCode());
        relationDO.setVerified(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode());
        //渠道信息，如果不是渠道会员，为Null
        relationDO.setChannel(subMemberChannel);

        relationDO.setInnerStatus(MemberInnerStatusEnum.NEW.getCode());
        relationDO.setOuterStatus(MemberOuterStatusEnum.TO_PLATFORM_VERIFY.getCode());
        relationDO.setValidateMsg("");
        relationDO.setStatus(MemberStatusEnum.NORMAL.getCode());
        //权限（只有平台才能修改会员权限，所以这里不需要设置权限）
        relationDO.setRelationAuth(null);

        //工作流任务，查找入库流程
        ProcessBO depositProcess = memberProcessRuleService.findMemberProcessKey(relationDO, MemberProcessTypeEnum.MEMBER_DEPOSITORY);
        relationDO.setValidateTask(new MemberValidateTaskDO("", depositProcess.getProcessKey(), MemberProcessTypeEnum.MEMBER_DEPOSITORY.getCode()));

        relationRepository.saveAndFlush(relationDO);

        //创建上级会员的等级配置
        MemberLevelConfigDO memberLevelConfigDO =baseMemberLevelConfigService.findLevel(relationDO, subMemberLevel);
        //第二步骤：设置“下级”的等级、权益、信用等信息
        MemberLevelRightDO levelDO = new MemberLevelRightDO();
        levelDO.setMemberId(upperMember.getId());
        levelDO.setRoleId(upperRole.getId());
        levelDO.setSubMemberId(subMember.getId());
        levelDO.setSubRoleId(subRole.getId());
        levelDO.setLevelConfig(memberLevelConfigDO);
        levelDO.setLevel(memberLevelConfigDO == null ? 0 : memberLevelConfigDO.getLevel());
        levelDO.setLevelTag(memberLevelConfigDO == null ? "" : memberLevelConfigDO.getLevelTag());
        levelDO.setScore(0);
        levelDO.setCurrentPoint(0);
        levelDO.setSumPoint(0);
        levelDO.setSumReturnMoney(new BigDecimal(0));
        levelDO.setSumUsedPoint(0);
        levelDO.setRelation(relationDO);

        //设置信用信息
        MemberCreditDO creditDO = new MemberCreditDO();
        creditDO.setMemberId(upperMember.getId());
        creditDO.setRoleId(upperRole.getId());
        creditDO.setSubMemberId(subMember.getId());
        creditDO.setSubRoleId(subRole.getId());
        creditDO.setAfterSaleCommentPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setCreditPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setRegisterYearsPoint(0);
        creditDO.setTradeCommentPoint(0);
        creditDO.setRelation(relationDO);
        creditDO.setRegisterPointUpdateTime(LocalDateTime.now());
        creditDO.setTradeCommentStars(0);
        creditDO.setTradeCommentCount(0);
        creditDO.setAvgTradeCommentStar(ServiceConfig.DEFAULT_TRADE_COMMENT_STAR);

        //关联到会员关系
        relationDO.setLevelRight(levelDO);
        relationDO.setCredit(creditDO);
        relationRepository.saveAndFlush(relationDO);
        
        //将平台后台的下级会员成为当前用户的下级会员
        //MemberRelationDO firstBySubMemberIdAndSubRoleIdAndRelType = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(subMember.getId(), subRole.getId(), MemberRelationTypeEnum.PLATFORM.getCode());

        //第六步骤：外部审核记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, relationDO.getRole().getRoleName(), MemberValidateHistoryOperationEnum.CREATE_SUB_MEMBER, MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()), "");

        //由于平台会员可以“无需审核”，所以这里要判断是否执行会员入库流程
        if(subMemberPlatformRelation.getOuterStatus().equals(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode())) {
            if(depositProcess.getEmptyProcess()) {
                relationDO.setDepositTime(LocalDateTime.now());
                relationDO.setInnerStatus(MemberInnerStatusEnum.VERIFY_PASSED.getCode());
                relationDO.setOuterStatus(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode());
                relationDO.setVerified(MemberValidateStatusEnum.VERIFY_PASSED.getCode());
                relationDO.setDepositTime(LocalDateTime.now());
            } else {
                //启动会员入库流程
                Wrapper<WorkflowTaskResultBO> taskResult = workflowFeignService.startMemberProcess(relationDO);
                if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                    return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
                }

                relationDO.setInnerStatus(taskResult.getData().getInnerStatus());
                relationDO.getValidateTask().setTaskId(taskResult.getData().getTaskId());
                relationDO.setOuterStatus(MemberOuterStatusEnum.DEPOSITING.getCode());
            }
            relationRepository.saveAndFlush(relationDO);

            //外部流转记录
            baseMemberHistoryService.saveMemberOuterHistory(relationDO, subMemberPlatformRelation.getRole().getRoleName(), MemberValidateHistoryOperationEnum.PLATFORM_VALIDATE, MemberOuterStatusEnum.getCodeMsg(subMemberPlatformRelation.getOuterStatus()), "");

            //报表统计、实时消息
            reportFeignService.reportMemberValidate(relationDO.getId(), relationDO.getMemberId(), relationDO.getRoleId(), null, relationDO.getInnerStatus(), relationDO.getValidateTask().getProcessTypeEnum());
            messageFeignService.sendMemberValidateMessage(relationDO);
        }

        //如果审核通过，通知支付服务创建资金账户，创建会员授信
        payFeignService.notifyMemberAssetAccount(relationDO);
        payFeignService.notifyMemberCredit(relationDO);
        return Wrapper.success();
    }


    /**
     * 修改平台会员信息
     * 只能在会员新建下级会员后，才能修改下级会员的信息
     * @param updateBO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updatePlatformMember(UpdatePlatformMemberBO updateBO) {
        //更新会员信息
        Long oldRoleId = updateBO.getRelationDO().getSubRoleId();
        List<AuthBO> oldRoleAuthBOList = updateBO.getRelationDO().getSubRole().getRoleAuth().getAuth();
        boolean isRoleUpdate = !oldRoleId.equals(updateBO.getRoleDO().getId());

        //平台会员的上下级关系
        MemberRelationDO adminRelationDO = updateBO.getRelationDO();
        if(adminRelationDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        //会员的管理员用户
        MemberUserDO memberUserDO = adminRelationDO.getSubMember().getUsers().stream().filter(user -> user.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
        if(memberUserDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_USER_DOES_NOT_EXIST);
        }

        //修改平台会员的上下级关系
        adminRelationDO.setSubMemberTypeEnum(updateBO.getMemberTypeDO().getTypeEnum());
        adminRelationDO.setSubRoleId(updateBO.getRoleDO().getId());
        adminRelationDO.setSubRole(updateBO.getRoleDO());
        adminRelationDO.setSubRoleName(updateBO.getRoleDO().getRoleName());

        //权限
        if(isRoleUpdate) {
            MemberRelationAuthDO relationAuth = adminRelationDO.getRelationAuth();
            if(relationAuth != null) {
                relationAuth.setAuth(updateBO.getRoleDO().getRoleAuth().getAuth());
                relationAuthRepository.saveAndFlush(relationAuth);
            }
        }

        //修改等级
        //由于平台的下属会员都是“平台会员”，所以不需要根据会员等级类型进行判断
        MemberLevelConfigDO upperMemberLevelConfigDO = baseMemberLevelConfigService.findLevel(adminRelationDO, updateBO.getLevel());
        MemberLevelRightDO levelDO = adminRelationDO.getLevelRight();
        levelDO.setMemberId(adminRelationDO.getMemberId());
        levelDO.setRoleId(adminRelationDO.getRoleId());
        levelDO.setSubMemberId(adminRelationDO.getSubMemberId());
        levelDO.setSubRoleId(updateBO.getRoleDO().getId());
        levelDO.setLevelConfig(upperMemberLevelConfigDO);
        levelDO.setLevel(upperMemberLevelConfigDO == null ? 0 : upperMemberLevelConfigDO.getLevel());
        levelDO.setLevelTag(upperMemberLevelConfigDO == null ? "" : upperMemberLevelConfigDO.getLevelTag());
        memberLevelRightRepository.saveAndFlush(levelDO);

        //保存平台上下级关系
        relationRepository.saveAndFlush(adminRelationDO);

        //修改信用信息
        MemberCreditDO creditDO = adminRelationDO.getCredit();
        creditDO.setSubMemberId(updateBO.getRelationDO().getSubMemberId());
        creditDO.setSubRoleId(updateBO.getRoleDO().getId());
        memberCreditRepository.saveAndFlush(creditDO);

        //如果更改了角色，更改内、外部审核记录
        if(isRoleUpdate) {
            baseMemberHistoryService.updateHistorySubRoleId(updateBO.getRelationDO().getSubMemberId(), oldRoleId, updateBO.getRoleDO().getId(), updateBO.getRoleDO().getRoleName(), updateBO.getName());
        }

        //修改会员信息，合并权限
        MemberDO memberDO = updateBO.getRelationDO().getSubMember();
        memberDO.setAccount(updateBO.getPhone());
        memberDO.setPhone(updateBO.getPhone());
        memberDO.setCountryCode(updateBO.getCountryCode());
        memberDO.setName(updateBO.getName());
        memberDO.setEmail(updateBO.getEmail());

        if(isRoleUpdate) {
            memberDO.getRoles().removeIf(roleDO -> roleDO.getId().equals(oldRoleId));
            memberDO.getRoles().add(updateBO.getRoleDO());
        }

        MemberAuthDO memberAuth = memberDO.getMemberAuth();
        if(isRoleUpdate && memberDO.getRoles().size() > 1) {
            List<List<AuthBO>> allAuthBOList = relationRepository.findBySubMemberIdAndSubRoleIdAndRelType(adminRelationDO.getSubMemberId(), adminRelationDO.getSubRoleId(), MemberRelationTypeEnum.PLATFORM.getCode()).stream().map(relationDO -> relationDO.getRelationAuth().getAuth()).collect(Collectors.toList());
            memberAuth.setAuth(AuthBOUtils.mergeAndDistinct(allAuthBOList));

        } else {
            memberAuth.setAuth(updateBO.getRoleDO().getRoleAuth().getAuth());
        }
        memberAuthRepository.saveAndFlush(memberAuth);

        //修改会员的管理员角色
        if(isRoleUpdate) {
            MemberRoleDO memberRoleDO = memberDO.getMemberRoles().stream().filter(mr -> mr.getTypeEnum().equals(MemberUserAuthTypeEnum.ADMIN.getCode())).findFirst().orElse(null);
            if(memberRoleDO != null) {
                memberRoleDO.setAuth(memberAuth.getAuth());
                memberRoleRepository.saveAndFlush(memberRoleDO);

                if (memberDO.getRoles().size() > 1) {
                    List<MemberRoleDO> memberRoleDOList = memberDO.getMemberRoles().stream().filter(mr -> mr.getTypeEnum().equals(MemberUserAuthTypeEnum.NORMAL.getCode())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(memberRoleDOList)) {
                        //这里比较重要！移除所有用户关于旧角色的权限
                        List<List<AuthBO>> excludeList = memberDO.getRoles().stream().map(role -> role.getRoleAuth().getAuth()).collect(Collectors.toList());
                        memberRoleDOList.forEach(mr -> {
                            List<AuthBO> memberRoleAuthBOList = mr.getAuth();
                            AuthBOUtils.removeFromSource(memberRoleAuthBOList, oldRoleAuthBOList, excludeList);
                            mr.setAuth(memberRoleAuthBOList);
                        });
                        memberRoleRepository.saveAll(memberRoleDOList);
                    }

                    List<MemberUserAuthDO> userAuthList = memberDO.getUsers().stream().filter(user -> user.getTypeEnum().equals(MemberUserAuthTypeEnum.NORMAL.getCode())).map(MemberUserDO::getUserAuth).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(userAuthList)) {
                        List<List<AuthBO>> excludeList = memberDO.getRoles().stream().map(roleDO -> roleDO.getRoleAuth().getAuth()).collect(Collectors.toList());
                        userAuthList.forEach(userAuth -> {
                            List<AuthBO> userAuthBOList = userAuth.getAuth();
                            AuthBOUtils.removeFromSource(userAuthBOList, oldRoleAuthBOList, excludeList);
                            userAuth.setAuth(userAuthBOList);
                        });

                        memberUserAuthRepository.saveAll(userAuthList);
                    }
                } else {
                    List<MemberRoleDO> memberRoleDOList = memberDO.getMemberRoles().stream().filter(mr -> mr.getTypeEnum().equals(MemberUserAuthTypeEnum.NORMAL.getCode())).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(memberRoleDOList)) {
                        memberRoleDOList.forEach(mr -> mr.setAuth(updateBO.getRoleDO().getRoleAuth().getAuth()));
                        memberRoleRepository.saveAll(memberRoleDOList);
                    }

                    List<MemberUserAuthDO> userAuthList = memberDO.getUsers().stream().filter(user -> user.getTypeEnum().equals(MemberUserAuthTypeEnum.NORMAL.getCode())).map(MemberUserDO::getUserAuth).collect(Collectors.toList());
                    if (!CollectionUtils.isEmpty(userAuthList)) {
                        userAuthList.forEach(userAuth -> userAuth.setAuth(updateBO.getRoleDO().getRoleAuth().getAuth()));
                        memberUserAuthRepository.saveAll(userAuthList);
                    }
                }
            }
        }

        //修改管理员用户的账号
        memberUserDO.setName(updateBO.getName());
        memberUserDO.setAccount(updateBO.getPhone());
        memberUserDO.setPhone(updateBO.getPhone());
        memberUserDO.setEmail(updateBO.getEmail());
        memberUserDO.getUserAuth().setAuth(memberAuth.getAuth());
        memberUserDO.setCountryCode(updateBO.getCountryCode());
        memberUserRepository.saveAndFlush(memberUserDO);

        return Wrapper.success();
    }

    /**
     * 修改会员上下级关系
     *
     * @param updateRelationBO 接口参数
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> updateMemberRelation(UpdateMemberRelationBO updateRelationBO) {
        //创建上下级关系，以及审核状态
        MemberRelationDO relationDO = updateRelationBO.getRelationDO();
        relationDO.setSubRoleId(updateRelationBO.getSubRoleDO().getId());
        relationDO.setSubRole(updateRelationBO.getSubRoleDO());
        relationDO.setSubRoleName(updateRelationBO.getSubRoleDO().getRoleName());
        relationDO.setSubMemberTypeEnum(updateRelationBO.getMemberTypeDO().getTypeEnum());
        //非平台会员没有权限
        relationDO.setRelationAuth(null);

        //修改后状态为“待提交审核”（手动再提交审核）
        relationDO.setInnerStatus(MemberInnerStatusEnum.NEW.getCode());
        relationDO.setOuterStatus(MemberOuterStatusEnum.TO_PLATFORM_VERIFY.getCode());

        //保存上下级关系
        relationRepository.saveAndFlush(relationDO);

        MemberLevelConfigDO memberLevelConfigDO = baseMemberLevelConfigService.findLevel(relationDO, updateRelationBO.getLevel());
        //更改“下级”的等级、权益、信用等信息
        MemberLevelRightDO levelDO = relationDO.getLevelRight();
        if(levelDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_LEVEL_DOES_NOT_EXIST);
        }
        levelDO.setSubMemberId(updateRelationBO.getSubMember().getId());
        levelDO.setSubRoleId(updateRelationBO.getSubRoleDO().getId());
        levelDO.setLevelConfig(memberLevelConfigDO);
        levelDO.setLevel(memberLevelConfigDO == null ? 0 : memberLevelConfigDO.getLevel());
        levelDO.setLevelTag(memberLevelConfigDO == null ? "" : memberLevelConfigDO.getLevelTag());
        levelDO.setRelation(relationDO);
        memberLevelRightRepository.saveAndFlush(levelDO);

        //更改信用信息
        MemberCreditDO creditDO = relationDO.getCredit();
        if(creditDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_CREDIT_CONFIG_DOES_NOT_EXIST);
        }

        creditDO.setSubMemberId(updateRelationBO.getSubMember().getId());
        creditDO.setSubRoleId(updateRelationBO.getSubRoleDO().getId());
        creditDO.setRelation(relationDO);
        memberCreditRepository.saveAndFlush(creditDO);

        return Wrapper.success();
    }

    /**
     * 删除平台会员
     * @param memberDO 要删除的会员
     * @param relationDO 要删除的与平台会员的上下级关系
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> deletePlatformMember(MemberDO memberDO, MemberRelationDO relationDO) {
        //删除与MemberDO相关的
        //删除角色与用户、组织
        memberRoleRepository.deleteAll(memberDO.getMemberRoles());
        memberUserRepository.deleteAll(memberDO.getUsers());
        memberOrganizationRepository.deleteAll(memberDO.getOrgs());

        //删除下属的升级规则
        memberLevelRuleConfigRepository.deleteByMemberIdAndRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberRightConfigRepository.deleteByMemberIdAndRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberLevelConfigRepository.deleteByMemberIdAndRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());

        //删除权益、信用、历史记录等
        baseMemberHistoryService.deleteHistoryBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberAfterSaleHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberComplainHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberTradeCommentHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberLevelHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberRightHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberRightSpendHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(relationDO.getSubMemberId(), relationDO.getSubRoleId());

        relationRepository.delete(relationDO);
        memberRepository.delete(memberDO);


        return Wrapper.success();
    }

    /**
     * 删除上下级关系
     *
     * @param relationDO 上下级关系
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> deleteMemberRelation(MemberRelationDO relationDO) {
        //各种历史记录
        baseMemberHistoryService.deleteHistoryByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberAfterSaleHistoryRepository.deleteByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberComplainHistoryRepository.deleteByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberTradeCommentHistoryRepository.deleteByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberLevelHistoryRepository.deleteByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberRightHistoryRepository.deleteByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());
        memberRightSpendHistoryRepository.deleteByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getSubMemberId(), relationDO.getSubRoleId());


        relationRepository.delete(relationDO);
        return Wrapper.success();
    }

    /**
     * 删除平台会员和角色
     * @param relationDO 平台会员上下级关系
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> deletePlatformMemberAndRole(MemberRelationDO relationDO) {
        MemberDO memberDO = relationDO.getSubMember();
        if(memberDO.getAccount().equals(ServiceConfig.PLATFORM_SUPER_ADMIN_ACCOUNT)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        RoleDO roleDO = relationDO.getSubRole();
        if(memberDO.getRoles().size() == 1 && memberDO.getRoles().iterator().next().getId().equals(roleDO.getId())) {
            return deleteMemberCompletely(memberDO, roleDO);
        }

        Long deleteMemberId = memberDO.getId();
        Long deleteRoleId = roleDO.getId();

        //删除与MemberDO相关的角色
        memberDO.getRoles().remove(roleDO);
        memberRepository.saveAndFlush(memberDO);

        relationRepository.deleteAllBySubMemberIdAndSubRoleId(memberDO.getId(), roleDO.getId());

        //删除下属的升级规则
        memberLevelRuleConfigRepository.deleteByMemberIdAndRoleId(deleteMemberId, deleteRoleId);
        memberRightConfigRepository.deleteByMemberIdAndRoleId(deleteMemberId, deleteRoleId);
        memberLevelConfigRepository.deleteByMemberIdAndRoleId(deleteMemberId, deleteRoleId);

        //删除权益、信用、历史记录等
        memberLevelRightRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberCreditRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        baseMemberHistoryService.deleteHistoryBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberAfterSaleHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberComplainHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberTradeCommentHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberLevelHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberRightHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberRightSpendHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);

        return Wrapper.success();
    }

    /**
     * 会员只有一个角色的情况下，彻底删除平台会员和角色
     * @param memberDO 要删除的会员
     * @param roleDO 要删除的角色
     * @return 删除结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> deleteMemberCompletely(MemberDO memberDO, RoleDO roleDO) {
        if(memberDO.getAccount().equals(ServiceConfig.PLATFORM_SUPER_ADMIN_ACCOUNT)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        Long deleteMemberId = memberDO.getId();
        Long deleteRoleId = roleDO.getId();

        //删除与MemberDO相关的
        //删除角色与用户、组织
        memberRoleRepository.deleteAll(memberDO.getMemberRoles());
        memberUserRepository.deleteAll(memberDO.getUsers());
        memberOrganizationRepository.deleteAll(memberDO.getOrgs());

        //删除上下级关系
        relationRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        //移除角色关联关系、会员
        memberDO.getRoles().clear();
        memberRepository.delete(memberDO);

        //删除下属的升级规则
        memberLevelRuleConfigRepository.deleteByMemberIdAndRoleId(deleteMemberId, deleteRoleId);
        memberRightConfigRepository.deleteByMemberIdAndRoleId(deleteMemberId, deleteRoleId);
        memberLevelConfigRepository.deleteByMemberIdAndRoleId(deleteMemberId, deleteRoleId);

        //删除权益、信用、历史记录等
        memberLevelRightRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberCreditRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        baseMemberHistoryService.deleteHistoryBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberAfterSaleHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberComplainHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberTradeCommentHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberLevelHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberRightHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);
        memberRightSpendHistoryRepository.deleteAllBySubMemberIdAndSubRoleId(deleteMemberId, deleteRoleId);

        return Wrapper.success();
    }

    /**
     * 平台会员，新增角色
     * @param processBO        角色关联的平台会员审核流程
     * @param operatorRoleName 登录用户的当前会员角色
     * @param adminMemberDO 平台管理员
     * @param adminRole 平台管理员的角色
     * @param memberDO 会员
     * @param roleDO   新增的角色
     * @param memberAdminRole 会员下属的管理员角色
     * @param memberAdminUser 会员下属的管理员
     * @param memberName 会员名称
     * @param memberRegisterDetails 注册资料
     * @return 新增结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> addMemberRole(ProcessBO processBO, String operatorRoleName, MemberDO adminMemberDO, RoleDO adminRole, MemberDO memberDO, RoleDO roleDO, MemberRoleDO memberAdminRole, MemberUserDO memberAdminUser, String memberName, List<MemberRegisterDetailDO> memberRegisterDetails) {
        //Step 1: 删除旧的注册资料，保存新的注册资料
        memberRegisterDetailRepository.deleteByMember(memberDO);

        memberRegisterDetails.forEach(memberRegisterDetailDO -> {
            memberRegisterDetailDO.setMember(memberDO);
            //如果是无需审核流程，将注册资料版本设置为“正在使用”
            if(processBO.getEmptyProcess()) {
                memberRegisterDetailDO.setVersion(MemberDetailVersionEnum.USING.getCode());
            }
        });
        memberRegisterDetailRepository.saveAll(memberRegisterDetails);

        memberDO.setRegisterDetails(new HashSet<>(memberRegisterDetails));

        //Step 2:设置新的角色和权限
        if(StringUtils.hasLength(memberName)) {
            memberDO.setName(memberName);
        }

        memberDO.getRoles().add(roleDO);
        memberDO.getMemberAuth().setAuth(AuthBOUtils.mergeAndDistinct(memberDO.getMemberAuth().getAuth(), roleDO.getRoleAuth().getAuth()));
        //由于存在循环关联实体，所以要先保存一下Member信息
        memberRepository.saveAndFlush(memberDO);

        //Step 3: 更改超级管理员角色和用户的权限
        memberAdminRole.setAuth(AuthBOUtils.mergeAndDistinct(memberAdminRole.getAuth(), roleDO.getRoleAuth().getAuth()));
        memberAdminUser.getUserAuth().setAuth(AuthBOUtils.mergeAndDistinct(memberAdminUser.getUserAuth().getAuth(), roleDO.getRoleAuth().getAuth()));
        memberRoleRepository.saveAndFlush(memberAdminRole);
        memberUserRepository.saveAndFlush(memberAdminUser);

        //Step 4：创建上下级关系，以及审核状态
        MemberRelationDO relationDO = new MemberRelationDO();
        relationDO.setCreateTime(LocalDateTime.now());
        relationDO.setMemberId(adminMemberDO.getId());
        relationDO.setMember(adminMemberDO);
        relationDO.setRoleId(adminRole.getId());
        relationDO.setRole(adminRole);
        relationDO.setSubMemberId(memberDO.getId());
        relationDO.setSubMember(memberDO);
        relationDO.setSubMemberTypeEnum(roleDO.getMemberType().getTypeEnum());
        //上级为平台，所以等级类型为平台会员
        relationDO.setSubMemberLevelTypeEnum(MemberLevelTypeEnum.PLATFORM.getCode());
        relationDO.setSubRoleId(roleDO.getId());
        relationDO.setSubRole(roleDO);
        relationDO.setSubRoleName(roleDO.getRoleName());
        relationDO.setRelType(MemberRelationTypeEnum.PLATFORM.getCode());
        relationDO.setRelSource(MemberRelationSourceEnum.ADD_ROLE.getCode());
        relationDO.setVerified(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode());
        relationDO.setValidateMsg("");
        relationDO.setStatus(MemberStatusEnum.NORMAL.getCode());
        //平台会员不需要渠道信息
        relationDO.setChannel(null);

        //权限
        MemberRelationAuthDO relationAuth = new MemberRelationAuthDO();
        relationAuth.setAuth(roleDO.getRoleAuth().getAuth());
        relationAuth.setRelation(relationDO);

        relationDO.setRelationAuth(relationAuth);
        //由于工作流需要dataId（不能为空或0），所以要先保存一下MemberRelationDO
        relationRepository.saveAndFlush(relationDO);

        //Step 5：调用工作流模块
        if(processBO.getEmptyProcess()) {
            relationDO.setValidateTask(new MemberValidateTaskDO("", processBO.getProcessKey(), MemberProcessTypeEnum.PLATFORM_VALIDATION.getCode()));
            relationDO.setInnerStatus(PlatformInnerStatusEnum.VERIFY_PASSED.getCode());
            relationDO.setOuterStatus(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode());
            relationDO.setVerified(MemberValidateStatusEnum.VERIFY_PASSED.getCode());
            relationDO.setDepositTime(LocalDateTime.now());
        } else {
            Wrapper<WorkflowTaskResultBO> taskResult = workflowFeignService.startMemberProcess(processBO.getProcessKey(), relationDO.getMemberId(), relationDO.getRoleId(), relationDO.getId());
            if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VALIDATE_WORKFLOW_ERROR);
            }

            relationDO.setInnerStatus(taskResult.getData().getInnerStatus());
            //工作流任务
            relationDO.setValidateTask(new MemberValidateTaskDO(taskResult.getData().getTaskId(), processBO.getProcessKey(), MemberProcessTypeEnum.PLATFORM_VALIDATION.getCode()));

            if (taskResult.getData().getInnerStatus().equals(PlatformInnerStatusEnum.VERIFY_NOT_PASSED.getCode())) {
                relationDO.setOuterStatus(MemberOuterStatusEnum.PLATFORM_VERIFY_NOT_PASSED.getCode());
            } else if (taskResult.getData().getInnerStatus().equals(PlatformInnerStatusEnum.VERIFY_PASSED.getCode())) {
                relationDO.setOuterStatus(MemberOuterStatusEnum.PLATFORM_VERIFY_PASSED.getCode());
                relationDO.setDepositTime(LocalDateTime.now());
            } else {
                relationDO.setOuterStatus(MemberOuterStatusEnum.PLATFORM_VERIFYING.getCode());
            }
        }

        //Step 6：设置“平台会员”的等级、权益、信用等信息
        //由于平台的下属会员都是“平台会员”，所以不需要根据会员等级类型进行判断
        MemberLevelConfigDO upperMemberLevelConfigDO = baseMemberLevelConfigService.findFirstLevel(relationDO);

        MemberLevelRightDO levelDO = new MemberLevelRightDO();
        levelDO.setMemberId(adminMemberDO.getId());
        levelDO.setRoleId(adminRole.getId());
        levelDO.setSubMemberId(memberDO.getId());
        levelDO.setSubRoleId(roleDO.getId());
        levelDO.setLevel(upperMemberLevelConfigDO == null ? 0 : upperMemberLevelConfigDO.getLevel());
        levelDO.setLevelTag(upperMemberLevelConfigDO == null ? "" : upperMemberLevelConfigDO.getLevelTag());
        levelDO.setLevelConfig(upperMemberLevelConfigDO);
        levelDO.setScore(0);
        levelDO.setCurrentPoint(0);
        levelDO.setSumPoint(0);
        levelDO.setSumReturnMoney(new BigDecimal(0));
        levelDO.setSumUsedPoint(0);
        levelDO.setRelation(relationDO);

        //设置信用信息
        MemberCreditDO creditDO = new MemberCreditDO();
        creditDO.setMemberId(adminMemberDO.getId());
        creditDO.setRoleId(adminRole.getId());
        creditDO.setSubMemberId(memberDO.getId());
        creditDO.setSubRoleId(roleDO.getId());
        creditDO.setAfterSaleCommentPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setCreditPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setRegisterYearsPoint(0);
        creditDO.setTradeCommentPoint(0);
        creditDO.setRelation(relationDO);
        creditDO.setRegisterPointUpdateTime(LocalDateTime.now());
        creditDO.setTradeCommentStars(0);
        creditDO.setTradeCommentCount(0);
        creditDO.setAvgTradeCommentStar(ServiceConfig.DEFAULT_TRADE_COMMENT_STAR);

        //关联到会员关系
        relationDO.setLevelRight(levelDO);
        relationDO.setCredit(creditDO);
        relationRepository.saveAndFlush(relationDO);

        //Step 7：“注册”的审核记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, operatorRoleName, MemberValidateHistoryOperationEnum.REGISTER, MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()), "");

        //异步通知报表服务发送实时消息
        reportFeignService.reportPlatformMemberValidate(relationDO.getId(), relationDO.getMemberId(), relationDO.getRoleId(), null, relationDO.getInnerStatus());

        //如果审核通过，通知支付服务创建资金账户、授信账户，通知物流服务创建初始化数据
        payFeignService.notifyMemberAssetAccount(relationDO);
        payFeignService.notifyMemberCredit(relationDO);
        logisticsFeignService.initMemberLogisticsAsync(relationDO);

        return Wrapper.success();
    }

    /**
     * 下级会员申请成为上级会员的下级
     * @param upperMemberId 上级会员Id
     * @param upperRoleId    上级会员角色Id
     * @param subMemberId 下级会员Id
     * @param subRoleId 下级会员角色Id
     * @param depositDetails 入库资料
     * @param qualities 资质证明文件
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> applyToBeSubMember(Long upperMemberId, Long upperRoleId, Long subMemberId, Long subRoleId, Map<String, Object> depositDetails, List<MemberQualityVO> qualities) {
        //规则：
        //1. 渠道会员可以申请成为渠道会员的下级会员
        //2. 商户会员可以申请成为商户会员的下级会员
        //3. 如果下级会员是渠道会员，且下级会员已经有另一个服务消费者角色在会员树中，不允许创建

        //会员不能成为自己的下级会员
        if(subMemberId.equals(upperMemberId)) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_CAN_NOT_BE_SUB_MEMBER_OF_SELF);
        }

        //当前会员没有审核通过，不能申请
        MemberRelationDO subRelation = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(subMemberId, subRoleId, MemberRelationTypeEnum.PLATFORM.getCode());
        if(subRelation == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        if(!subRelation.getVerified().equals(MemberValidateStatusEnum.VERIFY_PASSED.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_VERIFYING);
        }

        if(!subRelation.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_HAS_BEEN_FROZEN);
        }

        //判断是否已经是下级会员了，如果是被淘汰的，可以申请，状态改为正常
        MemberRelationDO existRelation = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(upperMemberId, upperRoleId, subMemberId, subRoleId);
        if(existRelation != null) {
            if(existRelation.getStatus().equals(MemberStatusEnum.ELIMINATED.getCode())) {
                return reApplyForSubMember(existRelation);
            } else if(existRelation.getStatus().equals(MemberStatusEnum.BLACK_LIST.getCode())) {
                return Wrapper.fail(ResponseCode.MC_MS_BLACKLIST_MEMBER_CAN_NOT_APPLY_FOR_SUB_MEMBER);
            } else {
                return Wrapper.fail(ResponseCode.MC_MS_IS_ALREADY_SUB_MEMBER);
            }
        }

        //判断上级会员
        MemberRelationDO upperRelation = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelType(upperMemberId, upperRoleId, MemberRelationTypeEnum.PLATFORM.getCode());
        if(upperRelation == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        if(!upperRelation.getVerified().equals(MemberValidateStatusEnum.VERIFY_PASSED.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_UPPER_MEMBER_VALIDATE_NOT_PASSED);
        }

        if(!upperRelation.getStatus().equals(MemberStatusEnum.NORMAL.getCode())) {
            return Wrapper.fail(ResponseCode.MC_MS_UPPER_MEMBER_STATUS_IS_NOT_NORMAL);
        }

        MemberDO upperMemberDO = upperRelation.getSubMember();
        RoleDO upperRoleDO = upperRelation.getSubRole();
        MemberDO subMemberDO = subRelation.getSubMember();
        RoleDO subRoleDO = subRelation.getSubRole();

        //检查入库资料
        Wrapper<List<MemberDepositoryDetailDO>> depositCheckResult = baseMemberDepositDetailService.checkMemberDepositoryDetail(upperMemberId, upperRoleId, subRoleDO, depositDetails);
        if(depositCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(depositCheckResult.getCode(), depositCheckResult.getMessage());
        }

        //检查资质文件
        Wrapper<List<MemberQualityDO>> qualityCheckResult = baseMemberQualificationService.checkMemberQualities(qualities);
        if(qualityCheckResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(qualityCheckResult.getCode(), qualityCheckResult.getMessage());
        }

        //规则1、2
        //上级会员等级类型
        Integer upperMemberLevelType = MemberLevelTypeEnum.getCodeByMemberType(upperRoleDO.getMemberType().getTypeEnum());
        //下级会员等级类型
        Integer subMemberLevelTypeEnum = MemberLevelTypeEnum.getCodeByMemberType(subRoleDO.getMemberType().getTypeEnum());
        if(!upperMemberLevelType.equals(subMemberLevelTypeEnum)) {
            if(upperMemberLevelType.equals(MemberLevelTypeEnum.MERCHANT.getCode())) {
                return Wrapper.fail(ResponseCode.MC_MS_NEED_MERCHANT_MEMBER_TYPE);
            } else {
                return Wrapper.fail(ResponseCode.MC_MS_NEED_CHANNEL_MEMBER_TYPE);
            }
        }

        //如果下级会员（当前会员）是渠道会员，判断是否已经有服务消费者角色在上下级关系树中
        if(subMemberLevelTypeEnum.equals(MemberLevelTypeEnum.CHANNEL.getCode()) && subRoleDO.getRoleType().getTypeEnum().equals(RoleTypeEnum.SERVICE_CONSUMER.getCode())) {
            List<MemberRelationDO> relationDOList = relationRepository.findAllByRelType(MemberRelationTypeEnum.OTHER.getCode());
            List<MemberRelationDO> upperRelationList = findUpperMemberRelationList(relationDOList, upperMemberId, upperRoleId, subMemberId);
            if (!CollectionUtils.isEmpty(upperRelationList)) {
                //判断是否有消费者角色存在于关系中
                if (upperRelationList.stream().anyMatch(relationDO -> (relationDO.getMemberId().equals(upperMemberId) && relationDO.getRole().getRoleType().getTypeEnum().equals(RoleTypeEnum.SERVICE_CONSUMER.getCode())) || (relationDO.getSubMemberId().equals(subMemberId) && relationDO.getSubRole().getRoleType().getTypeEnum().equals(RoleTypeEnum.SERVICE_CONSUMER.getCode())))) {
                    return Wrapper.fail(ResponseCode.MC_MS_MEMBER_HAS_CONSUMER_ROLE_IN_UPPER_MEMBER_RELATIONS);
                }
            }
        }

        //上级会员的等级配置
        MemberLevelConfigDO memberLevelConfigDO = baseMemberLevelConfigService.findFirstLevel(upperMemberId, upperRoleId, subRoleId);
        //如果是渠道会员，准备渠道信息
        ChannelTypeDO channelTypeDO = null;
        if(subMemberLevelTypeEnum.equals(MemberLevelTypeEnum.CHANNEL.getCode())) {
            //渠道类型默认设置为电商渠道
            channelTypeDO = channelTypeRepository.findAll().stream().filter(c -> c.getChannelTypeEnum().equals(MemberChannelTypeEnum.ECOMMERCE.getCode())).findFirst().orElse(null);
            if(channelTypeDO == null) {
                return Wrapper.fail(ResponseCode.MC_MS_MEMBER_CHANNEL_TYPE_DOES_NOT_EXIST);
            }
        }

        //创建上下级关系，以及审核状态
        MemberRelationDO relationDO = new MemberRelationDO();
        relationDO.setCreateTime(LocalDateTime.now());
        relationDO.setMemberId(upperMemberDO.getId());
        relationDO.setMember(upperMemberDO);
        relationDO.setRoleId(upperRoleDO.getId());
        relationDO.setRole(upperRoleDO);
        relationDO.setSubMemberId(subMemberId);
        relationDO.setSubMember(subMemberDO);
        relationDO.setSubRoleId(subRoleDO.getId());
        relationDO.setSubRole(subRoleDO);
        relationDO.setSubRoleName(subRoleDO.getRoleName());
        relationDO.setSubMemberTypeEnum(subRoleDO.getMemberType().getTypeEnum());
        relationDO.setSubMemberLevelTypeEnum(subMemberLevelTypeEnum);
        relationDO.setRelType(MemberRelationTypeEnum.OTHER.getCode());
        relationDO.setRelSource(MemberRelationSourceEnum.APPLY_TO_BE.getCode());
        relationDO.setVerified(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode());
        relationDO.setValidateMsg("");
        relationDO.setStatus(MemberStatusEnum.NORMAL.getCode());
        relationDO.setRelationAuth(null);
        relationDO.setUserId(0L);

        //如果是渠道会员，创建并关联渠道信息
        if(subRoleDO.getMemberType().getTypeEnum().equals(MemberTypeEnum.CHANNEL.getCode()) || subRoleDO.getMemberType().getTypeEnum().equals(MemberTypeEnum.CHANNEL_PERSONAL.getCode())) {
            MemberChannelDO channelDO = new MemberChannelDO();
            channelDO.setChannelType(channelTypeDO);
            //默认都为二级渠道
            channelDO.setLevel(ServiceConfig.MEMBER_CHANNEL_DEFAULT_LEVEL);
            channelDO.setChannelLevelTag(MemberStringEnum.MEMBER_CHANNEL_DEFAULT_LEVEL_TAG.getName());
            channelDO.setAgentArea(new AgentAreaBO());
            channelDO.setRemark("");
            relationDO.setChannel(channelDO);
        }

        MemberValidateTaskDO taskDO = new MemberValidateTaskDO("", "", MemberProcessTypeEnum.MEMBER_DEPOSITORY.getCode());
        relationDO.setValidateTask(taskDO);
        //保存上下级关系
        relationRepository.saveAndFlush(relationDO);

        //入库资料
        List<MemberDepositoryDetailDO> depositoryDetailList = depositCheckResult.getData();

        //判断是否需要入库审核，启动入库工作流
        ProcessBO depositProcess = memberProcessRuleService.findMemberProcessKey(upperMemberId, upperRoleId, subRoleDO, MemberProcessTypeEnum.MEMBER_DEPOSITORY);
        if(depositProcess.getEmptyProcess()) {
            relationDO.getValidateTask().setProcessKey(depositProcess.getProcessKey());
            //内外状态
            relationDO.setInnerStatus(MemberInnerStatusEnum.VERIFY_PASSED.getCode());
            relationDO.setOuterStatus(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode());
            relationDO.setVerified(MemberValidateStatusEnum.VERIFY_PASSED.getCode());
            //入库时间
            relationDO.setDepositTime(LocalDateTime.now());

            //入库资料设置为“正在使用”的版本
            depositoryDetailList.forEach(detail -> detail.setVersion(MemberDetailVersionEnum.USING.getCode()));
        } else {
            Wrapper<WorkflowTaskResultBO> taskResult = workflowFeignService.startMemberProcess(depositProcess.getProcessKey(), upperMemberId, upperRoleId, relationDO.getId());
            if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            relationDO.getValidateTask().setTaskId(taskResult.getData().getTaskId());
            relationDO.getValidateTask().setProcessKey(depositProcess.getProcessKey());

            //内外状态
            relationDO.setInnerStatus(taskResult.getData().getInnerStatus());
            relationDO.setOuterStatus(MemberOuterStatusEnum.DEPOSITING.getCode());
            relationDO.setVerified(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode());
        }

        //入库资料设置关联的MemberRelationDO
        depositoryDetailList.forEach(detail -> detail.setRelation(relationDO));
        memberDepositoryDetailRepository.saveAll(depositoryDetailList);

        //资质文件
        List<MemberQualityDO> qualityList = qualityCheckResult.getData();
        qualityList.forEach(quality -> quality.setRelation(relationDO));
        memberQualityRepository.saveAll(qualityList);

        relationDO.setDepositDetails(new HashSet<>(depositoryDetailList));
        relationDO.setQualities(new HashSet<>(qualityList));

        //第二步骤：设置“下级”的等级、权益、信用等信息
        MemberLevelRightDO levelDO = new MemberLevelRightDO();
        levelDO.setMemberId(upperMemberDO.getId());
        levelDO.setRoleId(upperRoleDO.getId());
        levelDO.setSubMemberId(subMemberDO.getId());
        levelDO.setSubRoleId(subRoleDO.getId());
        levelDO.setLevelConfig(memberLevelConfigDO);
        levelDO.setLevel(memberLevelConfigDO == null ? 0 : memberLevelConfigDO.getLevel());
        levelDO.setLevelTag(memberLevelConfigDO == null ? "" : memberLevelConfigDO.getLevelTag());
        levelDO.setScore(0);
        levelDO.setCurrentPoint(0);
        levelDO.setSumPoint(0);
        levelDO.setSumReturnMoney(new BigDecimal(0));
        levelDO.setSumUsedPoint(0);
        levelDO.setRelation(relationDO);

        //设置信用信息
        MemberCreditDO creditDO = new MemberCreditDO();
        creditDO.setMemberId(upperMemberDO.getId());
        creditDO.setRoleId(upperRoleDO.getId());
        creditDO.setSubMemberId(subMemberDO.getId());
        creditDO.setSubRoleId(subRoleDO.getId());
        creditDO.setAfterSaleCommentPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setCreditPoint(0);
        creditDO.setComplainPoint(0);
        creditDO.setRegisterYearsPoint(0);
        creditDO.setTradeCommentPoint(0);
        creditDO.setRelation(relationDO);
        creditDO.setRegisterPointUpdateTime(LocalDateTime.now());
        creditDO.setTradeCommentStars(0);
        creditDO.setTradeCommentCount(0);
        creditDO.setAvgTradeCommentStar(ServiceConfig.DEFAULT_TRADE_COMMENT_STAR);

        //关联到会员关系
        relationDO.setLevelRight(levelDO);
        relationDO.setCredit(creditDO);
        relationRepository.saveAndFlush(relationDO);

        //第六步骤：外部审核记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, subRoleDO.getRoleName(),  MemberValidateHistoryOperationEnum.APPLY_FOR_SUB_MEMBER,MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()),MemberValidateHistoryOperationEnum.APPLY_FOR_MEMBER.getMsg());

        //异步通知报表统计
        reportFeignService.addSubMember(upperMemberId,upperRoleId,LocalDateTime.now());

        //异步通知报表服务、消息服务发送实时消息
        reportFeignService.reportMemberValidate(relationDO.getId(), relationDO.getMemberId(), relationDO.getRoleId(),null, relationDO.getInnerStatus(), relationDO.getValidateTask().getProcessTypeEnum());
        //向上级会员、下级会员发送消息
        messageFeignService.sendMemberValidateMessage(relationDO, relationDO.getMemberId(), relationDO.getRoleId());
        messageFeignService.sendMemberValidateMessage(relationDO);

        //如果审核通过，通知支付服务创建资金账户
        payFeignService.notifyMemberAssetAccount(relationDO);
        payFeignService.notifyMemberCredit(relationDO);

        return Wrapper.success();
    }

    /**
     * 会员被淘汰后，重新申请为下级会员
     * @param relationDO 被淘汰的会员关系
     * @return 操作结果
     */
    @Transactional(rollbackFor = BusinessException.class)
    @Override
    public Wrapper<Void> reApplyForSubMember(MemberRelationDO relationDO) {
        //查找、启动会员入库流程
        ProcessBO depositProcess = memberProcessRuleService.findMemberProcessKey(relationDO, MemberProcessTypeEnum.MEMBER_DEPOSITORY);
        relationDO.getValidateTask().setProcessKey(depositProcess.getProcessKey());
        relationDO.getValidateTask().setProcessTypeEnum(MemberProcessTypeEnum.MEMBER_DEPOSITORY.getCode());

        //重置状态为“正常”
        relationDO.setValidateMsg("");
        relationDO.setStatus(MemberStatusEnum.NORMAL.getCode());

        if(depositProcess.getEmptyProcess()) {
            relationDO.setVerified(MemberValidateStatusEnum.VERIFY_PASSED.getCode());
            relationDO.setInnerStatus(MemberInnerStatusEnum.VERIFY_PASSED.getCode());
            relationDO.setOuterStatus(MemberOuterStatusEnum.DEPOSITORY_PASSED.getCode());
            relationDO.setDepositTime(LocalDateTime.now());
        } else {
            Wrapper<WorkflowTaskResultBO> taskResult = workflowFeignService.startMemberProcess(relationDO);
            if (taskResult.getCode() != ResponseCode.SUCCESS.getCode()) {
                return Wrapper.fail(taskResult.getCode(), taskResult.getMessage());
            }

            relationDO.setInnerStatus(taskResult.getData().getInnerStatus());
            relationDO.getValidateTask().setTaskId(taskResult.getData().getTaskId());
            relationDO.setOuterStatus(MemberOuterStatusEnum.DEPOSITING.getCode());
            relationRepository.saveAndFlush(relationDO);
        }

        //外部历史记录
        baseMemberHistoryService.saveMemberOuterHistory(relationDO, relationDO.getSubRoleName(), MemberValidateHistoryOperationEnum.APPLY_FOR_SUB_MEMBER, MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()), "");

        //如果审核通过，通知支付服务创建资金账户
        payFeignService.notifyMemberAssetAccount(relationDO);
        payFeignService.notifyMemberCredit(relationDO);

        return Wrapper.success();
    }

    /**
     * 查询上级会员的所有上下级关系，并筛选出包含下级会员Id的关系
     * @param relationDOList 所有会员关系
     * @param memberId 上级会员Id
     * @param roleId 上级会员角色Id
     * @param subMemberId 下级会员Id
     * @return 上级会员的上下级关系中包含下级会员Id的所有关系
     */
    private List<MemberRelationDO> findUpperMemberRelationList(List<MemberRelationDO> relationDOList, Long memberId, Long roleId, Long subMemberId) {
        if(CollectionUtils.isEmpty(relationDOList)) {
            return new ArrayList<>();
        }

        List<MemberRelationDO> upperMemberRelationDOList = new ArrayList<>();
        //查询所有上级
        List<MemberRelationDO> upperList = relationDOList.stream().filter(relation -> relation.getSubMemberId().equals(memberId) && relation.getSubRoleId().equals(roleId)).collect(Collectors.toList());
        while (!CollectionUtils.isEmpty(upperList)) {
            upperMemberRelationDOList.addAll(upperList);

            //再次查询上级
            List<MemberRelationDO> finalUpperList = upperList;
            upperList = relationDOList.stream().filter(relationDO -> finalUpperList.stream().anyMatch(upper -> relationDO.getSubMemberId().equals(upper.getMemberId()) && relationDO.getSubRoleId().equals(upper.getRoleId()))).collect(Collectors.toList());
            upperList.removeIf(u -> upperMemberRelationDOList.stream().anyMatch(exist -> exist.getMemberId().equals(u.getMemberId()) && exist.getRoleId().equals(u.getRoleId()) && exist.getSubMemberId().equals(u.getSubMemberId()) && exist.getSubRoleId().equals(u.getSubRoleId())));
        }

        //查询所有下级
        List<MemberRelationDO> subList = relationDOList.stream().filter(relation -> relation.getMemberId().equals(memberId) && relation.getRoleId().equals(roleId)).collect(Collectors.toList());
        while (!CollectionUtils.isEmpty(subList)) {
            upperMemberRelationDOList.addAll(subList);

            //再次查询下级
            List<MemberRelationDO> finalSubList = subList;
            subList = relationDOList.stream().filter(relationDO -> finalSubList.stream().anyMatch(sub -> relationDO.getMemberId().equals(sub.getSubMemberId()) && relationDO.getRoleId().equals(sub.getSubRoleId()))).collect(Collectors.toList());
            subList.removeIf(u -> upperMemberRelationDOList.stream().anyMatch(exist -> exist.getMemberId().equals(u.getMemberId()) && exist.getRoleId().equals(u.getRoleId()) && exist.getSubMemberId().equals(u.getSubMemberId()) && exist.getSubRoleId().equals(u.getSubRoleId())));
        }

        return upperMemberRelationDOList.stream().filter(relationDO -> relationDO.getMemberId().equals(subMemberId) || relationDO.getSubMemberId().equals(subMemberId)).collect(Collectors.toList());
    }
}
